package com.core.netty.http;

import com.core.netty.http.work.MySerlvet;
import com.core.netty.http.work.MySerlvetUrl;
import com.core.netty.http.work.SerlvetUtil;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

import java.io.File;
import java.util.*;

public class HttpServer {
    private volatile List<String> classNames = new ArrayList<>();

    public HttpServer(int port) {

        initSerlvet();
        //SqlHelper.init();
        bind(port);


    }

    private void bind(int port) {
        long start = new Date().getTime();

        EventLoopGroup boss = new NioEventLoopGroup();
        EventLoopGroup worker = new NioEventLoopGroup();

        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(boss, worker);
            bootstrap.channel(NioServerSocketChannel.class);
            bootstrap.option(ChannelOption.SO_BACKLOG, 1024); // 连接数
            //bootstrap.option(ChannelOption.TCP_NODELAY, true); // 不延迟，消息立即发送
            bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true); // 长连接
            bootstrap.childHandler(new HttpIniter());
            ChannelFuture channelFuture = bootstrap.bind(port).sync();
            if (channelFuture.isSuccess()) {
                long end = new Date().getTime();
                System.err.println("启动所需时长:" + (end - start) + "ms");
                System.err.println("启动Netty服务成功，端口号：" + port);
            }
            // 关闭连接
            channelFuture.channel().closeFuture().sync();

        } catch (Exception e) {
            System.err.println("启动Netty服务异常，异常信息：" + e.getMessage());
            e.printStackTrace();
        } finally {
            boss.shutdownGracefully();
            worker.shutdownGracefully();
        }
    }

    private void initSerlvet() {
        doScanner("com");
        doInstance();
        SerlvetUtil.getMap().forEach((k, v) -> {
            v.init();
        });
    }

    private void doScanner(String packageName) {

        //把所有的.替换成/
        //URL url = this.getClass().getClassLoader().getResource("/" + packageName.replaceAll("\\.", "/"));

        //把所有的.替换成/
        //URL url = this.getClass().getClassLoader().getResource("/" + packageName.replaceAll("\\.", "/"));
        String path = this.getClass().getResource(".").getPath();
        path = path.substring(0, path.indexOf("/com/core"));

        File dir = new File(path + "/" + packageName.replaceAll("\\.", "/"));

        for (File file : dir.listFiles()) {
            if (file.isDirectory()) {
                //递归读取包
                doScanner(packageName + "." + file.getName());
            } else {

                String className = packageName + "." + file.getName().replace(".class", "");
                classNames.add(className);
            }
        }

        //return classNames;
    }


    private void doInstance() {

        if (classNames.isEmpty()) {
            return;
        }

        Map<String, Object> ioc = new HashMap<>();
        for (String className : classNames) {
            try {
                //把类搞出来,反射来实例化(只有加@MyController需要实例化)
                Class<?> clazz = Class.forName(className);

                if (clazz.isAnnotationPresent(MySerlvetUrl.class)) {
                    MySerlvetUrl url = clazz.getDeclaredAnnotation(MySerlvetUrl.class);

                    if ("HttpMySerlvet".equals(clazz.getSuperclass().getSimpleName())) {
                        SerlvetUtil.put(url.value(), (MySerlvet) clazz.newInstance());
                    }

                } else {
                    continue;
                }


            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }
        }


    }


    public static void main(String[] args) throws InterruptedException {
        new HttpServer(8897);
    }

}
